from flask import jsonify
import logging
import json
import smtplib
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from datetime import datetime, timedelta
from models import Record, BillCategory, BillSubCategory

# 配置日志
logging.basicConfig(level=logging.ERROR)
logger = logging.getLogger(__name__)

def api_response(data=None, message="success", code=200):
    """统一API响应格式"""
    response = {
        "code": code,
        "message": message,
        "data": data
    }
    return response,code

def safe_json_serialize(obj, default=None):
    """
    安全的JSON序列化函数
    确保所有字符串都使用双引号（JSON标准）
    """
    if default is None:
        default = lambda o: f"<{type(o).__name__}>"
    
    try:
        # 首先尝试直接序列化
        json_str = json.dumps(obj, default=default, ensure_ascii=False)
        # 重新解析确保格式正确
        validated_obj = json.loads(json_str)
        return validated_obj
    except Exception as e:
        logger.error(f"JSON serialization error: {str(e)}")
        # 如果序列化失败，返回错误信息
        return {
            "error": "Serialization failed",
            "message": str(e),
            "original_type": type(obj).__name__
        }

def send_weekly_report_email(email, user_id, start_date, end_date):
    """发送周消费报告邮件"""
    try:
        # 获取用户的消费记录
        records = Record.query.filter(
            Record.user_id == user_id,
            Record.record_date >= start_date,
            Record.record_date <= end_date
        ).order_by(Record.record_date.desc()).all()
        
        # 计算总支出和总收入
        total_expense = sum(record.amount for record in records if record.type == 0)
        total_income = sum(record.amount for record in records if record.type == 1)
        
        # 按分类统计支出
        category_expenses = {}
        for record in records:
            if record.type == 0:  # 支出
                category_name = record.category.name if record.category else "未知分类"
                if category_name in category_expenses:
                    category_expenses[category_name] += record.amount
                else:
                    category_expenses[category_name] = record.amount
        
        # 生成HTML邮件内容
        html_content = f"""
        <html>
        <head>
            <meta charset="utf-8">
            <style>
                body {{ font-family: Arial, sans-serif; }}
                .header {{ background-color: #f5f5f5; padding: 20px; text-align: center; }}
                .summary {{ background-color: #e9f7ef; padding: 15px; margin: 20px 0; border-radius: 5px; }}
                .records {{ margin: 20px 0; }}
                table {{ width: 100%; border-collapse: collapse; }}
                th, td {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
                th {{ background-color: #f2f2f2; }}
                .category-chart {{ margin: 20px 0; }}
                .chart-bar {{ display: flex; align-items: center; margin: 5px 0; }}
                .chart-label {{ width: 150px; }}
                .chart-bar-inner {{ background-color: #4CAF50; height: 20px; }}
            </style>
        </head>
        <body>
            <div class="header">
                <h2>家庭晚餐消费报告</h2>
                <p>统计周期: {start_date.strftime('%Y年%m月%d日')} - {end_date.strftime('%Y年%m月%d日')}</p>
            </div>
            
            <div class="summary">
                <h3>消费概览</h3>
                <p>总支出: <strong>¥{total_expense:.2f}</strong></p>
                <p>总收入: <strong>¥{total_income:.2f}</strong></p>
                <p>净支出: <strong>¥{total_expense - total_income:.2f}</strong></p>
            </div>
            
            <div class="category-chart">
                <h3>分类支出</h3>
        """
        
        # 添加分类图表
        for category, amount in sorted(category_expenses.items(), key=lambda x: x[1], reverse=True):
            percentage = (amount / total_expense * 100) if total_expense > 0 else 0
            bar_width = percentage * 3  # 放大3倍以便显示
            html_content += f"""
                <div class="chart-bar">
                    <div class="chart-label">{category}</div>
                    <div style="width: {max(1, bar_width)}px; background-color: #4CAF50; height: 20px;"></div>
                    <div style="margin-left: 10px;">¥{amount:.2f} ({percentage:.1f}%)</div>
                </div>
            """
        
        # 添加详细记录表格
        html_content += """
            </div>
            
            <div class="records">
                <h3>详细记录</h3>
                <table>
                    <tr>
                        <th>日期</th>
                        <th>分类</th>
                        <th>子分类</th>
                        <th>描述</th>
                        <th>金额</th>
                        <th>类型</th>
                    </tr>
        """
        
        for record in records:
            category_name = record.category.name if record.category else "未知分类"
            sub_category_name = record.sub_category.name if record.sub_category else ""
            record_type = "支出" if record.type == 0 else "收入"
            html_content += f"""
                    <tr>
                        <td>{record.record_date.strftime('%Y-%m-%d')}</td>
                        <td>{category_name}</td>
                        <td>{sub_category_name}</td>
                        <td>{record.description or ''}</td>
                        <td>¥{record.amount:.2f}</td>
                        <td>{record_type}</td>
                    </tr>
            """
        
        html_content += """
                </table>
            </div>
        </body>
        </html>
        """
        
        # 发送邮件
        smtp_server = os.getenv('MAIL_SERVER', 'smtp.example.com')
        smtp_port = int(os.getenv('MAIL_PORT', 587))
        sender_email = os.getenv('MAIL_USERNAME', 'your_email@example.com')
        sender_password = os.getenv('MAIL_PASSWORD', 'your_password')
        
        # 如果没有配置邮件服务器，则只记录日志
        if smtp_server == 'smtp.example.com':
            logger.info(f"邮件服务器未配置，仅记录邮件内容: 发送到 {email}")
            logger.info(f"邮件内容预览: {html_content[:500]}...")
            return True
        
        # 创建邮件
        message = MIMEMultipart("alternative")
        message["Subject"] = f"家庭晚餐消费报告 - {start_date.strftime('%Y-%m-%d')}至{end_date.strftime('%Y-%m-%d')}"
        message["From"] = sender_email
        message["To"] = email
        
        # 添加HTML内容
        html_part = MIMEText(html_content, "html", "utf-8")
        message.attach(html_part)
        
        # 发送邮件
        with smtplib.SMTP(smtp_server, smtp_port) as server:
            server.starttls()
            server.login(sender_email, sender_password)
            server.sendmail(sender_email, email, message.as_string())
        
        logger.info(f"成功发送邮件到 {email}")
        return True
    except Exception as e:
        logger.error(f"发送邮件失败: {str(e)}")
        return False

def register_error_handlers(app):
    """注册错误处理器"""
    
    @app.errorhandler(404)
    def not_found(error):
        return api_response(None, "资源不存在", 404)
    
    @app.errorhandler(500)
    def internal_error(error):
        # 记录详细的错误信息
        logger.error(f"Internal server error: {str(error)}")
        return api_response(None, "服务器内部错误: " + str(error), 500)
    
    @app.errorhandler(400)
    def bad_request(error):
        return api_response(None, "请求参数错误", 400)